/**
 * XMLContentHandler.java 21 juil. 07
 * 
 * Copyright (c) 2007 windu.2b <jcaddie@windu2b.org>. All Rights Reserved.
 * 
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 * Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.windu2b.jcaddie.io.xml;

import java.net.*;
import java.util.*;

import org.windu2b.jcaddie.model.*;
import org.windu2b.jcaddie.model.UserPreferences.*;
import org.windu2b.jcaddie.tools.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;

/**
 * @author windu
 * 
 */
public class XMLCatalogContentHandler extends DefaultHandler
{
	private Catalog	                    catalog;


	private String	                    category;


	private String	                    category_id;


	private Hashtable<String, Category>	categories;


	private StringBuffer	            chaine;


	private String	                    name;


	private Content	                    icon;


	private Float	                    price;


	private Float	                    poids;


	private String	                    unit;




	/**
	 * 
	 * Constructeur par défaut
	 * 
	 */
	public XMLCatalogContentHandler( Catalog catalog )
	{
		super();
		chaine = new StringBuffer();
		this.catalog = catalog;
		categories = new Hashtable<String, Category>();
	}




	/**
	 * 
	 * Evènement envoyé au démarrage du parsing du flux XML.
	 * 
	 * @throws SAXException
	 *             en cas de problème quelquonque ne permettant pas de se lancer
	 *             dans l'analyse du document.
	 * 
	 * @see org.xml.sax.ContentHandler#startDocument()
	 * 
	 */
	@Override
	public void startDocument() throws SAXException
	{
	}




	/**
	 * 
	 * Evènement envoyé à la fin de l'analyse du flux XML.
	 * 
	 * @throws SAXException
	 *             en cas de problème quelquonque ne permettant pas de
	 *             considérer l'analyse du document comme étant complète.
	 * 
	 * @see org.xml.sax.ContentHandler#endDocument()
	 * 
	 */
	@Override
	public void endDocument() throws SAXException
	{

	}




	/**
	 * Evènement reçu à chaque fois que l'analyseur rencontre une balise XML
	 * ouvrante.
	 * 
	 * @param nameSpaceURI
	 *            l'url de l'espace de nommage.
	 * @param localName
	 *            le nom local de la balise.
	 * @param qName
	 *            nom de la balise en version 1.0
	 *            <code>nameSpaceURI + ":" + localName</code>
	 * @param attr
	 *            La liste des attributs pour cette balise
	 * @throws SAXException
	 *             si la balise ne correspond pas à ce qui est attendu, comme
	 *             par exemple non respect d'une DTD.
	 * 
	 * @see org.xml.sax.ContentHandler#startElement(java.lang.String,
	 *      java.lang.String, java.lang.String, org.xml.sax.Attributes)
	 * 
	 */
	@Override
	public void startElement( String nameSpaceURI, String localName,
	        String qName, Attributes attr ) throws SAXException
	{
		/**
		 * Ouverture de la balise <code>XML_MARKUP_CATEGORY</code>
		 */
		if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_CATEGORY.toString() ) )
		{
			String iconName = attr.getValue( attr
			        .getIndex( XMLCaddiesMarkup.XML_MARKUP_CATEGORY_ICON
			                .toString() ) );
			if( iconName != null && !iconName.equals( "" ) )
				icon = new URLContent( getContent( iconName ) );
			else
				icon = null;
			category_id = attr.getValue( attr
			        .getIndex( XMLCaddiesMarkup.XML_MARKUP_CATEGORY_ID
			                .toString() ) );
			category = attr.getValue( attr
			        .getIndex( XMLCaddiesMarkup.XML_MARKUP_CATEGORY_NAME
			                .toString() ) );
			categories.put( category,
			        new Category( category_id, category, icon ) );
		}
	}




	private Content getContent( String iconFileName )
	{
		URL url = ImageInJAR.getInstance().getImage( iconFileName );
		if ( url == null )
			throw new IllegalArgumentException( "unknown resource "
			        + iconFileName );
		else return new URLContent( url );
	}




	/**
	 * 
	 * Evènement reçu à chaque fermeture de balise.
	 * 
	 * @see org.xml.sax.ContentHandler#endElement(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 * 
	 */
	@Override
	public void endElement( String nameSpaceURI, String localName, String qName )
	        throws SAXException
	{
		/**
		 * Fermeture de la balise <code>XML_MARKUP_PRODUCT</code> On crée un
		 * objet <code>CatalogPieceOfProduct</code> avec tous les éléments qui
		 * le compose
		 */
		if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_PRODUCT.toString() ) )
		{
			CatalogPieceOfProduct product = new CatalogPieceOfProduct( name,
			        icon, getCategory( category_id ), price, poids, Unit
			                .valueOf( unit.toUpperCase() ) );
			catalog.add( categories.get( category ), product );
		}

		/**
		 * Fermeture de la balise <code>XML_MARKUP_PRODUCT_NAME</code>
		 */
		else if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_PRODUCT_NAME
		        .toString() ) )
		{
			name = chaine.toString().trim();
		}

		/**
		 * Fermeture de la balise <code>XML_MARKUP_PRODUCT_PRICE</code>
		 */
		else if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_PRODUCT_PRICE
		        .toString() ) )
		{
			price = Float.valueOf( chaine.toString().trim() );
		}

		/**
		 * Fermeture de la balise <code>XML_MARKUP_PRODUCT_POIDS</code>
		 */
		else if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_PRODUCT_POIDS
		        .toString() ) )
		{
			poids = Float.valueOf( chaine.toString().trim() );
		}

		/**
		 * Fermeture de la balise <code>XML_MARKUP_PRODUCT_UNIT</code>
		 */
		else if ( localName.equals( XMLCaddiesMarkup.XML_MARKUP_PRODUCT_UNIT
		        .toString() ) )
		{
			unit = chaine.toString().trim();
		}

		// On purge le StringBuffer
		chaine.delete( 0, chaine.length() );
	}




	/**
	 * 
	 * Evenement recu a chaque fois que l'analyseur rencontre des caracteres
	 * (entre deux balises).
	 * 
	 * @param ch
	 *            les caracteres proprement dits.
	 * @param start
	 *            le rang du premier caractere a traiter effectivement.
	 * @param length
	 *            le rang du dernier caractere a traiter effectivement
	 * 
	 * @see org.xml.sax.ContentHandler#characters(char[], int, int)
	 * 
	 */
	@Override
	public void characters( char[] ch, int start, int length )
	        throws SAXException
	{
		chaine.append( new String( ch, start, length ) );
	}




	/**
	 * 
	 * Renvoie une référence vers l'objet <code>Category</code> désigné par
	 * l'id <code>category_id</code> Si cet objet n'existe pas, il est
	 * préalablement créé
	 * 
	 * @param category_id
	 * 
	 * @return
	 */
	private Category getCategory( String category_id )
	{
		if ( categories.get( category_id ) == null )
		{
			categories.put( category_id, new Category( category_id, category ) );
		}

		return categories.get( category_id );
	}
}
